﻿using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using VisionDesigner;

namespace VM.Start.Common.Hik
{
    public class RImage : CMvdImage
    {

        /// <summary>
        /// 加载图像并转换为3通道（RGB）
        /// </summary>
        /// <param name="filepath">图像文件路径</param>
        /// <param name="mVD_PIXEL_FORMAT">像素格式</param>
        public void LoadImagePath(string filepath)
        {
            try
            {
                using (Bitmap bitmap = new Bitmap(filepath))
                {
                    // 检查图像是否包含 Alpha 通道
                    if (bitmap.PixelFormat == System.Drawing.Imaging.PixelFormat.Format32bppArgb)
                    {
                        // 创建一个新的 Bitmap 对象，用于存储 RGB 图像
                        using (Bitmap rgbBitmap = new Bitmap(bitmap.Width, bitmap.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb))
                        {
                            // 使用 Graphics 将原始图像绘制到新图像
                            using (Graphics g = Graphics.FromImage(rgbBitmap))
                            {
                                g.DrawImage(bitmap, 0, 0);
                            }

                            // 调用 ConvertBitmap2MVDImage，将新图像传递给函数
                            ConvertBitmap2MVDImage(rgbBitmap, this);
                        }
                    }
                    else
                    {
                        // 如果原始图像不是 Alpha 格式，直接处理
                        ConvertBitmap2MVDImage(bitmap, this);
                    }
                }

            }
            catch (Exception ex)
            {
                // 6. 捕获并记录异常信息
                Console.WriteLine($"图像加载失败：{ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 图像转换：Bitmap -> CMvdImage
        /// </summary>
        /// <param name="cHaclonImg">[IN]Bitmap图像</param>
        /// <param name="cMvdImage">[INOUT]CMvdImage图像</param>
        /// <remarks>只支持Mon8和RGB24，不支持伪彩图</remarks>
        public void ConvertBitmap2MVDImage(Bitmap cBitmapImg, CMvdImage cMvdImg)
        {
            // 参数合法性判断
            if (null == cBitmapImg || null == cMvdImg)
            {
                throw new MvdException(MVD_MODULE_TYPE.MVD_MODUL_APP, MVD_ERROR_CODE.MVD_E_PARAMETER_ILLEGAL);
            }

            // 判断像素格式
            if (System.Drawing.Imaging.PixelFormat.Format8bppIndexed != cBitmapImg.PixelFormat && System.Drawing.Imaging.PixelFormat.Format24bppRgb != cBitmapImg.PixelFormat)
            {
                throw new MvdException(MVD_MODULE_TYPE.MVD_MODUL_APP, MVD_ERROR_CODE.MVD_E_SUPPORT);
            }

            Int32 nImageWidth = cBitmapImg.Width;
            Int32 nImageHeight = cBitmapImg.Height;
            Int32 nChannelNum = 0;
            BitmapData bitmapData = null;

            try
            {
                // 获取图像信息
                if (System.Drawing.Imaging.PixelFormat.Format8bppIndexed == cBitmapImg.PixelFormat) // 灰度图
                {
                    bitmapData = cBitmapImg.LockBits(new Rectangle(0, 0, nImageWidth, nImageHeight)
                                                                 , ImageLockMode.ReadOnly
                                                                 , System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
                    cMvdImg.InitImage(Convert.ToUInt32(nImageWidth), Convert.ToUInt32(nImageHeight), MVD_PIXEL_FORMAT.MVD_PIXEL_MONO_08);
                    nChannelNum = 1;
                }
                else if (System.Drawing.Imaging.PixelFormat.Format24bppRgb == cBitmapImg.PixelFormat) // 彩色图
                {
                    bitmapData = cBitmapImg.LockBits(new Rectangle(0, 0, nImageWidth, nImageHeight)
                                                                , ImageLockMode.ReadOnly
                                                                , System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                    cMvdImg.InitImage(Convert.ToUInt32(nImageWidth), Convert.ToUInt32(nImageHeight), MVD_PIXEL_FORMAT.MVD_PIXEL_RGB_RGB24_C3);
                    nChannelNum = 3;
                }

                // 考虑图像是否4字节对齐，bitmap要求4字节对齐，而mvdimage不要求对齐
                if (0 == nImageWidth % 4) // 4字节对齐时，直接拷贝
                {
                    Marshal.Copy(bitmapData.Scan0, cMvdImg.GetImageData().stDataChannel[0].arrDataBytes, 0, nImageWidth * nImageHeight * nChannelNum);
                }
                else // 按步长逐行拷贝
                {
                    // 每行实际占用字节数
                    Int32 nRowPixelByteNum = nImageWidth * nChannelNum + 4 - (nImageWidth * nChannelNum % 4);
                    // 每行首字节首地址
                    IntPtr bitmapDataRowPos = IntPtr.Zero;
                    for (int i = 0; i < nImageHeight; i++)
                    {
                        // 获取每行第一个像素值的首地址
                        bitmapDataRowPos = new IntPtr(bitmapData.Scan0.ToInt64() + nRowPixelByteNum * i);
                        Marshal.Copy(bitmapDataRowPos, cMvdImg.GetImageData().stDataChannel[0].arrDataBytes, i * nImageWidth * nChannelNum, nImageWidth * nChannelNum);
                    }
                }

                // bitmap彩色图按BGR存储，而MVDimg按RGB存储，改变存储顺序
                // 交换R和B
                if (System.Drawing.Imaging.PixelFormat.Format24bppRgb == cBitmapImg.PixelFormat)
                {
                    byte bTemp;
                    byte[] bMvdImgData = cMvdImg.GetImageData().stDataChannel[0].arrDataBytes;
                    for (int i = 0; i < nImageWidth * nImageHeight; i++)
                    {
                        bTemp = bMvdImgData[3 * i];
                        bMvdImgData[3 * i] = bMvdImgData[3 * i + 2];
                        bMvdImgData[3 * i + 2] = bTemp;
                    }
                }
            }
            finally
            {
                cBitmapImg.UnlockBits(bitmapData);
            }

        }
    }
}
